﻿namespace PayPal.Tests
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using PayPal.AdaptivePayments;
    using PayPal.Platform.SDK;

    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class AdaptivePaymentsTests
    {
        private const string UserIp = "127.0.0.1";
        private const string Memo = "WebMatrix Integration";
        private const string DeviceId = "Test Device";

        public AdaptivePaymentsTests()
        {
            PayPal.Profile.Initialize(
                "msft_1284494024_biz_api1.yahoo.com",
                "1284494030",
                "AXmPHOGl57wrwF1dy49VI0W9gisLAWm4raYoWQy9KHCtpd7kLlSQcsFG",
                "sandbox");

            PayPal.Profile.Language = "en_US";
            PayPal.Profile.CancelUrl = "http://www.google.com";
            PayPal.Profile.IpnUrl = "http://www.yahoo.com";
            PayPal.Profile.ReturnUrl = "http://www.microsoft.com";
            PayPal.Profile.CurrencyCode = "USD";
        }

        [TestMethod]
        public void TestSimplePay()
        {
            string receiver = "isv_1284493468_biz@yahoo.com";
            decimal amount = decimal.Parse("20.0");
            string sender = "james_1284183860_per@yahoo.com";

            PayResponse response = SimplePay.Execute(
                    receiver,
                    amount,
                    sender,
                    Memo,
                    UserIp,
                    DeviceId);

            Assert.AreEqual("CREATED", response.paymentExecStatus);
        }

        [TestMethod]
        public void TestChainedPay()
        {
            Receiver primaryReceiver = new Receiver();
            primaryReceiver.amount = decimal.Parse("20.0");
            primaryReceiver.email = "isv_1284493468_biz@yahoo.com";

            string sender = "james_1284183860_per@yahoo.com";
            List<Receiver> receivers = new List<Receiver>();
            Receiver receiver = new Receiver();
            receiver.email = "msft_1284494024_biz@yahoo.com";
            receiver.amount = decimal.Parse("15.0");
            receivers.Add(receiver);

            PayResponse response = ChainedPay.Execute(primaryReceiver, receivers, sender, Memo, UserIp, DeviceId);

            Assert.AreEqual("CREATED", response.paymentExecStatus);
        }

        [TestMethod]
        public void TestConvertCurrency()
        {
            CurrencyType baseCur = new CurrencyType();
            baseCur.code = "USD";
            baseCur.amount = decimal.Parse("1.0");
            CurrencyType[] curType = { baseCur };
            string[] convertToCurrencyList = { "EUR" };

            ConvertCurrencyResponse res = ConvertCurrency.Execute(curType, convertToCurrencyList);

            Assert.AreEqual(AckCode.Success, res.responseEnvelope.ack);
        }

        [TestMethod]
        public void TestImplicitChainedPay()
        {
            string senderEmail = "msft_1284494024_biz@yahoo.com";
            Receiver primaryReceiver = new Receiver();
            primaryReceiver.amount = decimal.Parse("10.0");
            primaryReceiver.email = "isv_1284493468_biz@yahoo.com";

            List<Receiver> secondaryReceivers = new List<Receiver>();
            Receiver rec = new Receiver();
            rec.email = "james_1284182736_biz@yahoo.com";
            rec.amount = decimal.Parse("5.0");
            secondaryReceivers.Add(rec);

            PayResponse response = ImplicitChainedPay.Execute(primaryReceiver, secondaryReceivers, senderEmail, Memo, UserIp, DeviceId);

            Assert.AreEqual("COMPLETED", response.paymentExecStatus);
        }

        [TestMethod]
        public void TestImplicitParallelPay()
        {
            string senderEmail = "msft_1284494024_biz@yahoo.com";

            List<Receiver> secondaryReceivers = new List<Receiver>();

            Receiver rec1 = new Receiver();
            rec1.amount = decimal.Parse("10.0");
            rec1.email = "isv_1284493468_biz@yahoo.com";

            Receiver rec2 = new Receiver();
            rec2.email = "james_1284182736_biz@yahoo.com";
            rec2.amount = decimal.Parse("5.0");

            secondaryReceivers.Add(rec1);
            secondaryReceivers.Add(rec2);

            PayResponse res = ImplicitParallelPay.Execute(secondaryReceivers, senderEmail, Memo, UserIp, DeviceId);

            Assert.AreEqual("COMPLETED", res.paymentExecStatus);
        }

        [TestMethod]
        public void TestImplicitSimplePay()
        {
            string senderEmail = "msft_1284494024_biz@yahoo.com";
            string receiver = "isv_1284493468_biz@yahoo.com";
            string amount = "20.0";

            PayResponse response = ImplicitSimplePay.Execute(
                receiver,
                senderEmail,
                decimal.Parse(amount),
                Memo,
                UserIp,
                DeviceId);

            Assert.AreEqual("COMPLETED", response.paymentExecStatus);
        }

        [TestMethod]
        public void TestParallelPay()
        {
            string sender = "james_1284183860_per@yahoo.com";

            List<Receiver> receivers = new List<Receiver>();

            Receiver rec1 = new Receiver();
            rec1.amount = decimal.Parse("10.0");
            rec1.email = "isv_1284493468_biz@yahoo.com";

            Receiver rec2 = new Receiver();
            rec2.email = "james_1284182736_biz@yahoo.com";
            rec2.amount = decimal.Parse("5.0");

            receivers.Add(rec1);
            receivers.Add(rec2);

            PayResponse response = ParallelPay.Execute(receivers, sender, Memo, UserIp, DeviceId);

            Assert.AreEqual("CREATED", response.paymentExecStatus);
        }

        /// <summary>
        /// To run this test you need to provide a valid preapproval key in the test body. To do this:
        ///     1. Run the TestSimplePreapproval() test to retrieve a valid key.
        ///     2. Browse to https://sandbox.paypal.com/webscr?cmd=_ap-preapproval&preapprovalkey={yourKey} 
        ///         replacing your key value and accept the preaproval.
        ///     3. Remove the [Ignore] attribute and run the test.
        /// </summary>
        [TestMethod]
        [Ignore]        
        public void TestPreapprovedChainedPay()
        {
            string sender = "james_1284183860_per@yahoo.com";

            Receiver primaryReceiver = new Receiver();
            primaryReceiver.amount = decimal.Parse("20.0");
            primaryReceiver.email = "isv_1284493468_biz@yahoo.com";

            List<Receiver> receivers = new List<Receiver>();
            Receiver receiver = new Receiver();
            receiver.email = "msft_1284494024_biz@yahoo.com";
            receiver.amount = decimal.Parse("15.0");
            receivers.Add(receiver);

            string preapprovalkey = "PA-70285214166297348";

            PayResponse response = PreapprovedChainedPay.Execute(primaryReceiver, preapprovalkey, receivers, sender, Memo, UserIp, DeviceId);

            Assert.AreEqual("COMPLETED", response.paymentExecStatus);
        }

        [TestMethod]
        public void TestSimplePreapproval()
        {
            string senderEmail = "james_1284183860_per@yahoo.com";
            decimal maxTotalAmountForAllPayments = decimal.Parse("100.0");
            decimal maxAmountPerPayment = decimal.Parse("10.0");
            int maxNumberOfPayments = 10;

            PreapprovalResponse res = SimplePreapproval.Execute(
                                                                senderEmail,
                                                                DateTime.Today,
                                                                maxTotalAmountForAllPayments,
                                                                maxAmountPerPayment,
                                                                maxNumberOfPayments,
                                                                DateTime.Today.AddDays(7),
                                                                Memo, 
                                                                UserIp, 
                                                                DeviceId);
            
            Debug.Write(res.preapprovalKey); //// Retrieve Preapproval key from this line

            Assert.AreEqual(AckCode.Success, res.responseEnvelope.ack);
        }

        /// <summary>
        /// To run this test you need to provide a valid preapproval key in the test body. To do this:
        ///     1. Run the TestSimplePreapproval() test to retrieve a valid key.
        ///     2. Browse to https://sandbox.paypal.com/webscr?cmd=_ap-preapproval&preapprovalkey={yourKey} replacing your key value and accept the preaproval.
        ///     3. Remove the [Ignore] attribute and run the test.
        /// </summary>
        [TestMethod]
        [Ignore]
        public void TestPreapprovedParallelPay()
        {
            string sender = "james_1284183860_per@yahoo.com";
            List<Receiver> receivers = new List<Receiver>();

            Receiver receiver1 = new Receiver();
            receiver1.amount = decimal.Parse("20.0");
            receiver1.email = "isv_1284493468_biz@yahoo.com";
            receivers.Add(receiver1);

            Receiver receiver2 = new Receiver();
            receiver2.email = "msft_1284494024_biz@yahoo.com";
            receiver2.amount = decimal.Parse("15.0");
            receivers.Add(receiver2);

            string preapprovalkey = "PA-70285214166297348";

            PayResponse response = PreapprovedParallelPay.Execute(receivers, preapprovalkey, sender, Memo, UserIp, DeviceId);

            Assert.AreEqual("COMPLETED", response.paymentExecStatus);
        }

        /// <summary>
        /// To run this test you need to provide a valid preapproval key in the test body. To do this:
        ///     1. Run the TestSimplePreapproval() test to retrieve a valid key.
        ///     2. Browse to https://sandbox.paypal.com/webscr?cmd=_ap-preapproval&preapprovalkey={yourKey} replacing your key value and accept the preaproval.
        ///     3. Remove the [Ignore] attribute and run the test.
        /// </summary>
        [TestMethod]
        [Ignore]
        public void TestPreapprovedSimplePay()
        {
            string sender = "james_1284183860_per@yahoo.com";
            string receiver = "isv_1284493468_biz@yahoo.com";
            string preapprovalkey = "PA-70285214166297348";
            decimal amount = decimal.Parse("10.0");

            PayResponse response = PreapprovedSimplePay.Execute(
                                                                receiver,
                                                                amount,
                                                                preapprovalkey, 
                                                                sender, 
                                                                Memo, 
                                                                UserIp, 
                                                                DeviceId);

            Assert.AreEqual("COMPLETED", response.paymentExecStatus);        
        }

        [TestMethod]
        public void TestRefundCompletePayment()
        {
            RefundResponse response = RefundCompletePayment.Execute("AP-3A421775GP121541A", null);

            Assert.AreEqual(AckCode.Success, response.responseEnvelope.ack);
        }

        [TestMethod]
        public void TestRefundPartialPayment()
        {
            string payKey = "AP-3A421775GP121541A";

            Receiver receiver = new Receiver();
            receiver.amount = decimal.Parse("5.0");
            receiver.email = "isv_1284493468_biz@yahoo.com";

            Receiver[] receivers = { receiver };

            RefundResponse response = RefundPartialPayment.Execute(receivers, payKey, null);

            Assert.AreEqual(AckCode.Success, response.responseEnvelope.ack);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingSimplePay()
        {
            string receiver = "invalid_receiver@yahoo.com";
            decimal amount = decimal.Parse("20.0");
            string sender = "invalid_sender@yahoo.com";

            PayResponse response = SimplePay.Execute(receiver, amount, sender, Memo, UserIp, DeviceId);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingChainedPay()
        {
            Receiver primaryReceiver = new Receiver();
            string sender = "invalid_sender@yahoo.com";
            List<Receiver> receivers = new List<Receiver>();
            Receiver receiver = new Receiver();

            PayResponse response = ChainedPay.Execute(primaryReceiver, receivers, sender, Memo, UserIp, DeviceId);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingConvertCurrency()
        {
            CurrencyType baseCur = new CurrencyType();
            baseCur.code = "INVALIDCURRENCY";
            baseCur.amount = decimal.Parse("1.0");
            CurrencyType[] curType = { baseCur };
            string[] convertToCurrencyList = { "EUR" };

            ConvertCurrencyResponse res = ConvertCurrency.Execute(curType, convertToCurrencyList);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingImplicitChainedPay()
        {
            string senderEmail = "invalid_sender@yahoo.com";
            Receiver primaryReceiver = new Receiver();
 
            List<Receiver> secondaryReceivers = new List<Receiver>();

            PayResponse response = ImplicitChainedPay.Execute(primaryReceiver, secondaryReceivers, senderEmail, Memo, UserIp, DeviceId);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFalinigImplicitParallelPay()
        {
            string senderEmail = "invalid_sender@yahoo.com";

            List<Receiver> secondaryReceivers = new List<Receiver>();

            PayResponse res = ImplicitParallelPay.Execute(secondaryReceivers, senderEmail, Memo, UserIp, DeviceId);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingImplicitSimplePay()
        {
            string senderEmail = "invalid_sender@yahoo.com";
            string receiver = "invalid_receiver@yahoo.com";
            string amount = "20.0";

            PayResponse response = ImplicitSimplePay.Execute(receiver, senderEmail, decimal.Parse(amount), Memo, UserIp, DeviceId);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingParallelPay()
        {
            string sender = "invalid_sender@yahoo.com";
            List<Receiver> receivers = new List<Receiver>();

            PayResponse response = ParallelPay.Execute(receivers, sender, Memo, UserIp, DeviceId);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingPreapprovedChainedPay()
        {
            string sender = "invalid_sender@yahoo.com";
            Receiver primaryReceiver = new Receiver();
            List<Receiver> receivers = new List<Receiver>();
            string preapprovalkey = "INVALID-KEY";

            PayResponse response = PreapprovedChainedPay.Execute(primaryReceiver, preapprovalkey, receivers, sender, Memo, UserIp, DeviceId);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingSimplePreapproval()
        {
            string senderEmail = "invalid_sender@yahoo.com";
            decimal maxTotalAmountForAllPayments = decimal.Parse("100.0");
            decimal maxAmountPerPayment = decimal.Parse("10.0");
            int maxNumberOfPayments = 10;

            PreapprovalResponse res = SimplePreapproval.Execute(senderEmail, DateTime.Today, maxTotalAmountForAllPayments, maxAmountPerPayment, maxNumberOfPayments, DateTime.Today.AddDays(7), Memo, UserIp, DeviceId);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingPreapprovedSimplePay()
        {
            string sender = "invalid_sender@yahoo.com";
            string receiver = "invalid_receiver@yahoo.com";
            string preapprovalkey = "INVALID-KEY";
            decimal amount = decimal.Parse("10.0");

            PayResponse response = PreapprovedSimplePay.Execute(receiver, amount, preapprovalkey, sender, Memo, UserIp, DeviceId);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingPreapprovedParallelPay()
        {
            string sender = "invalid_sender@yahoo.com";
            List<Receiver> receivers = new List<Receiver>();
            string preapprovalkey = "INVALID-KEY";

            PayResponse response = PreapprovedParallelPay.Execute(receivers, preapprovalkey, sender, Memo, UserIp, DeviceId);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingRefundCompletePayment()
        {
            RefundResponse response = RefundCompletePayment.Execute("INVALID-KEY", null);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingRefundPartialPayment()
        {
            string payKey = "INVALID-KEY";
            Receiver[] receivers = new Receiver[] {};

            RefundResponse response = RefundPartialPayment.Execute(receivers, payKey, null);
        }

        [TestMethod]
        [ExpectedException(typeof(TransactionException))]
        public void TestFailingRefundTransaction()
        {
            RefundResponse response = RefundTransaction.Execute("INVALID-TRANSACTION-ID");
        }
    }
}